iT邦幫忙

2022 iThome 鐵人賽

DAY 3
1
Modern Web

這些那些你可能不知道我不知道的Web技術細節系列 第 3

你可能不知道在JavaScript裡的萬國碼

  • 分享至 

  • xImage
  •  

那時、天下人的口音言語、都是一樣。

他們往東邊遷移的時候、在示拿地遇見一片平原、就住在那裏。

他們彼此商量說、來罷、我們要作甎、把甎燒透了。他們就拿甎當石頭、又拿石漆當灰泥。

他們說、來罷、我們要建造一座城、和一座塔、塔頂通天、爲要傳揚我們的名、免得我們分散在全地上。

耶和華降臨要看看世人所建造的城和塔。

耶和華說、看哪、他們成爲一樣的人民、都是一樣的言語、如今旣作起這事來、以後他們所要作的事、就沒有不成就的了。

我們下去、在那裏變亂他們的口音、使他們的言語、彼此不通。

於是耶和華使他們從那裏分散在全地上.他們就停工、不造那城了。

因爲耶和華在那裏變亂天下人的言語、使衆人分散在全地上、所以那城名叫巴別。〈就是變亂的意思〉

-- 創世記11

從一封亂碼郵件開始說起

自己個人很少書寫電子郵件,收到的郵件也多數是某種活動、告知事項或廣告類信件。
有些時候會收到一些需要回信或是主動發信件的情況。絕大多數文字語言上都不是什麼問題。但就是偶爾會有一兩封信件在眼前呈現的是我看不懂得符號。

最近,我就收到過一封信件...是亂碼。

會呈現亂碼的原因,有很大程度是顯示軟體錯誤的解讀了信件內容。這種情況可能可以透過取得原始信件資料,在使用其他編輯器和解碼方式打開顯示。

以信件來說,常見的分成兩種類型:

  1. 純文字
  2. HTML文件

特別是HTML文件,會有一段以<meta/>標記內容使用的編碼方式(charset)。

我照往例將信件使用其他方式開啟,發現他已經標記著名是使用UTF-8方式處理了。
嘗試使用其他方式解碼也沒有得到可以閱讀的內容。換言之,這對我而言是已經損毀內容真正意義上的亂碼信件了。

像這樣的文字問題,不是只有編碼發生。至少Uncle Bob每年會遇到一次換行問題。

你最近一次處理文字檔時,因使用了『錯誤』的行末約定而遭遇到問題,是在什麼時候呢?我每年至少要遇到一次。
-- The Clean Coder

巧的是,我最近也遇到了換行問題。在過去也遇到過Python程式碼因為空白建(space)和製表鍵(tag)混合使用而造成的問題。

在計算機科學(資訊科學)上,巴別塔的程度不會比人類語言簡單,甚至我個人認為還更為複雜......

萬國碼

語言文字有非常多種。以我比較容易接觸到的就包含中文、英文、日文、韓文等等。甚至有一些語言並沒有完善的文字系統,像是閩南話;或是文字系統又因爲地區習慣有所差異,像中文就有臺灣繁體、香港繁體、大陸簡體等。儘管有些並不是看得懂、能了解意思,但單一個字符來說,對我而言並不是亂碼。

爲什麼在顯式上可以同時顯式這麼多種語言呢?這需要分成兩個部分:字體 和 編碼。

字體

先說一下並非本篇重點的 字體
首先對於顯式裝置,如LCD螢幕而言,畫面上的僅僅是一個個發光點而已。並不認識字體,因而需要有字體的描述檔案,讓顯式裝置明白如何顯式文字。

你可能可以在 C:\Windows\Fonts 或是 /usr/share/fonts/等路徑下看到各式各樣的字體檔案。常見的副檔名有:.ttf.otf.woff。你也可以利用FontForge製作自己的文字。

你或許正在使用思源體;或許聽過募資紅極一時的金萱體[^1];前陣子高中生創作的辰宇落雁體[^2]。

以中文來說,要完成大量的字體是件艱鉅的任務。但種種例子證明這並不是不可能的任務。

編碼

從上面看得到的字體,接著要看一下看不太到的編碼。

資訊在儲存的時候是以0和1的存在方式。有多少個0與1一起被解讀,限制了單位內能夠儲存的類型數量。

比如說只有兩個儲存位置,也就只存在 $2^2 = 4$ 種可能性。也就是:

  1. 00
  2. 01
  3. 10
  4. 11

如果有7個位置,也就有 $2^7 = 128$ 種可能性。對於英文算上大小寫和數字共62個字母而言非常足夠了。

但是對於中文五千以上個字,顯然不太足。更不用說多國語言了。

一個問題是: 用不到的字符,保留該位置太浪費空間
想想生活上有多少機會是一次同時會看非常多種語言的。多數情況下以1-2種表示。

所以會依照需求設計不同編碼方式。
以中文使用者來說,除了中文外,需要的有英文、阿拉伯數字,以及標點符號可能就夠了。但 還存在地區用語用字習慣差異,也就存在了大五碼Big5GB2312GBKCCCIICNS 11643

也就是說,同樣的0011010 0110110在不同需求下可能被表達成不同數量的不同文字。可能可以7個7個解讀成兩個文字,也可能需要14個一起被解讀。

萬國碼

但終究,還是有需要一次顯式多種語言文字的需求存在。因此出現了萬國碼(Unicode)。其中UTF-8更成了網際網路上最常使用的編碼方式,也是多數較近代出現程式原始碼的儲存方式[^4]。

自2009年以來,UTF-8一直是全球資訊網的最主要的編碼形式(對所有,而不僅是Unicode範圍內的編碼)(並由WHATWG宣布為強制性的「適用於所有事物(for all things)」,截止到2019年11月, 在所有網頁中,UTF-8編碼應用率高達94.3%(其中一些僅是ASCII編碼,因為它是UTF-8的子集)[^3]

0和1到ASCII

如果有7個位置,也就有 $2^7 = 128$ 種可能性。對於英文算上大小寫和數字共62個字母而言非常足夠了。

電腦發展之初,只需要英文即可。可以說 ASCII 是讓電腦進入到有文字的歷史時代。除了0和1,ASCII成爲了最原始的電腦母語。

隨者電腦的發展,主流的位元組(bytes)習慣以8個比特(bits)組合。也有了以現在來說更習慣使用的,也幾乎是ASCII的等義詞的擴充版ASCII(Extended ASCII, EASCII)。

在現在的今天,ASCII幾乎有一個特殊神聖的地位在。許多編碼方式與之相同,如UTF-8。可以說如果你的檔案是以ASCII文字書寫儲存,就幾乎不會存在開起來出現亂碼的問題

存文字的編碼申明訊息

程式語言原始碼多以純文字形式儲存。有一些純文字檔案會特別在開頭幾行說明使用什麼編碼方式,好讓編譯器、直譯器、編輯器可以正確解讀。譬如Python原始碼可以在開頭寫上# -*- coding: big5 -*-

以下面Python程式碼來說,如果使用big5儲存。

print("你好,世界怎麼跟得上臺灣")

然後使用Python3執行,你可能會得到錯誤訊息:

  File "hello.py", line 1
SyntaxError: Non-UTF-8 code starting with '\xa7' in file hello.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

不過如果你加上了編碼的申明訊息,這段程式就可以被正確執行了:

# -*- coding: big5 -*-
print("你好,世界怎麼跟得上臺灣")

要注意的是# -*- coding: big5 -*-也全是以可以被ASCII解讀的方式存在。

ASCII有一個特殊神聖的地位在

JavaScript世界裏的萬國碼

回到Web技術來看,JavaScript又是如何呢?為保險一些,或許原始碼都以ASCII能解讀的方式最好,但勢必有需要顯示ASCII以外的文字,又該如何是好?

在字面文字處理上,可以透過跳脫字元\u來輸入Unicodea碼。完整方式是\uhhhh,後面4個h表示以16進位表達的Unicodea碼。

比如可以先找到「你」的UTF-16編碼號碼

然後試著執行

console.log('\u4F60')

就會得到

依樣畫葫蘆,可以再執行看看:

console.log('\u4F60\u597D\uFF0C\u4E16\u754C')

就可以看到經典的「你好,世界」出現在眼前。

但並非所有的字都可以這樣表示,像是CJK UNIFIED IDEOGRAPH-28117就不行。須要寫成:

console.log("\ud860\udd17")

或是後來ES6支援的語法

console.log("\u{28117}")

不過該字在我使用的系統環境中並沒有對應的字體,因而顯示亂碼。

這也可以用來顯示emoji

console.log("給我一個大大的\u{1F44D}")
          // 給我一個大大的?

另外配和不同字體的使用,甚至可以顯示各式各樣的icon

不過其實如果使用UTF-8儲存原始碼,在我經驗上多數JavaScript執行環境,包含Google Chrome、Mozilla Firefox、Microsoft Edge和Node.js都不會有什麼問題。

參考資料

[^1]: Irvin, 炎上的金萱字型釋出記事 。取用時間:2022.08.27。
[^2]: 高中生自主學習計畫「自創手寫字體」被讚爆。取用時間:2022.08.27。
[^3]: 維基百科UTF-8。取用時間:2022.08.27。
[^4]: Python3預設以UTF-8解讀原始碼。(Using UTF-8 as the default source encoding)

本文同時發表於我的隨筆


上一篇
你可能不知道void也是一個運算子
下一篇
你可能不知道HTML Code Number
系列文
這些那些你可能不知道我不知道的Web技術細節33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言